package test.http;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.swing.text.BadLocationException;

import test.config.Config;

public class Connector {

	public static String proxyHost = Config.getProxyHost();
	public static int proxyPort = Config.getProxyPort();

	public static HttpURLConnection openConnection(String location, boolean useProxy)
			throws MalformedURLException, IOException,
			NoSuchAlgorithmException, KeyManagementException,
			BadLocationException {

		String connectionType = location.substring(0, 4);
		if (connectionType.equalsIgnoreCase("https")) {
			return connectHttps(location, useProxy);
		} else {
			return connectHttp(location, useProxy);
		}
	}

	public static HttpURLConnection connectHttps(final String location,
			boolean useProxy) throws MalformedURLException, IOException,
			NoSuchAlgorithmException, KeyManagementException,
			BadLocationException {
		final SSLContext ctx = SSLContext.getInstance("TLS");
		ctx.init(new KeyManager[0],
				new TrustManager[] { new DefaultTrustManager() },
				new SecureRandom());
		SSLContext.setDefault(ctx);

		final HttpsURLConnection connection;
		if (useProxy) {

			System.setProperty("http.proxyHost", proxyHost);
			System.setProperty("http.proxyPort", Integer.toString(proxyPort));
			final Proxy proxy = new Proxy(Proxy.Type.HTTP,
					new InetSocketAddress(proxyHost, proxyPort));
			connection = (HttpsURLConnection) new URL(location)
					.openConnection(proxy);
		} else {
			connection = (HttpsURLConnection) new URL(location)
					.openConnection();
		}
		connection.setHostnameVerifier(new NullHostnameVerifier());
		return connection;
	}

	public static HttpURLConnection connectHttp(String location,
			boolean useProxy) throws MalformedURLException, IOException,
			BadLocationException {

		HttpURLConnection connection;
		if (useProxy) {
			System.setProperty("http.proxyHost", proxyHost);
			System.setProperty("http.proxyPort", Integer.toString(proxyPort));
			final Proxy proxy = new Proxy(Proxy.Type.HTTP,
					new InetSocketAddress(proxyHost, proxyPort));
			connection = (HttpURLConnection) new URL(location)
					.openConnection(proxy);
		} else {
			connection = (HttpURLConnection) new URL(location).openConnection();
		}
		return connection;
	}

	private static class DefaultTrustManager implements X509TrustManager {
		@Override
		public void checkClientTrusted(final X509Certificate[] arg0,
				final String arg1) throws CertificateException {
		}

		@Override
		public void checkServerTrusted(final X509Certificate[] arg0,
				final String arg1) throws CertificateException {
		}

		@Override
		public X509Certificate[] getAcceptedIssuers() {
			return null;
		}
	}

	private static class NullHostnameVerifier implements HostnameVerifier {
		public boolean verify(final String hostname, final SSLSession session) {
			return true;
		}
	}
}
